package lelouet.datacenter.simulation.factorized;

import java.util.List;

import lelouet.datacenter.simulation.Event;
import lelouet.datacenter.simulation.events.AEvent;

/**
 * Objects that are working on time slots in a datacenter<br />
 * those objects support one way to work : they are {@link #reconfigure()
 * reconfigured}, then they can be asked when the {@link #nextEventTime() next
 * event will happen}, and be told to {@link #work(long) work} till a specified
 * time slot<br /< The behaviour of those time slots is the following :
 * <ol>
 * <li>external events of last slot are notified. This happens because events
 * may be caught by external listener, that will react to them and produce more
 * events. To solve this, we allow to handle infinitesimal sub-slot times for
 * succession of events</li>
 * <li>the work of the element is done, meaning it can produce events</li>
 * <li>the element catches upcoming internal events. That is, the events that
 * happen between two slot times, BEFORE external events.</li>
 * </ol>
 */
public interface WorkingElement {

	/**
	 * @return the assumed unique ID of this. No check should be done about
	 *         unicity, but having several elements with same id in a datacenter
	 *         may lead to unpredictable behaviour
	 */
	public String getId();

	/** @return the last slot time this stopped working, or was created. */
	public long getTime();

	/**
	 * @return the first end of slot time an event will happen on this. This can
	 *         be present time if an external element has produced events, as a
	 *         result of last events
	 */
	public long nextEventTime();

	/**
	 * ask this to work until given time, with present configuration at startup.<br />
	 * This may reconfigure parts of itself, and any such reconfiguration will
	 * generate events.
	 * 
	 * @param nextStop
	 *            the last slot time, starting from original point in ms, this
	 *            machine will work in. This is stopped just after this slot
	 *            time is ended. This means this actually works for <i>nextStop
	 *            - {@link #getTime()}</i> slots
	 * @return the list of {@link AEvent} that this work has produced.<br />
	 *         Note that this returns the notifications for events happening
	 *         just after nextStop's slot time, that have not already happened.
	 */
	public List<Event> work(long nextStop);

	/**
	 * forces this to reconfigure itself, so it knows how it will work for next
	 * slot times
	 */
	public void reconfigure();

}
